using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using UMC.Data;
using UMC.WorkFlow.Entities;

namespace UMC.WorkFlow.Form
{
    /// <summary>
    /// 把作业的管理信息放在默认的管理页面
    /// </summary>
    class FormMessage
    {
        IDictionary dictionary;
        public FormMessage(IDictionary dic)
        {
            this.dictionary = dic;
        }
        public void OnRespond(InstanceEvent taskEvent)
        {
            taskEvent.OnBeginProcess += OnBeginProcess;
            taskEvent.OnEndProcess += taskEvent_OnEndProcess;
        }
        public static Hashtable TaskData(ulong InstanceId)
        {
            var Hash = new Hashtable();
            var re = new System.Collections.Specialized.NameValueCollection();
            // var data = new List<TaskData>();

            // var keys = new List<String>();
            // var sqler = UMC.WorkFlow.TaskRuntime.Database.ObjectEntity<TaskData>();
            // sqler.Where.And().Equal(new TaskData { InstanceId = InstanceId })
            //     .Entities.Query(dr => re.Add(dr.DataName, dr.DataValue));

            Utility.Each(DataFactory.Instance().TaskData(InstanceId), dr => re.Add(dr.DataName, dr.DataValue));
            for (var i = 0; i < re.Count; i++)
            {
                Hash[re.GetKey(i)] = re.Get(i);
            }


            return Hash;

        }

        void OnBeginProcess(TaskInstance task, InstanceEventArgs e)
        {
            System.Collections.IDictionary dic = e.Runtime.Items;
            var list = TaskData(task.InstanceId).GetEnumerator();
            while (list.MoveNext())
            {

                dic[String.Format("UI.{0}", list.Key)] = Reflection.Parse(list.Value as string);
            }
            list = dictionary.GetEnumerator();
            while (list.MoveNext())
            {

                dic[String.Format("UI.{0}", list.Key)] = Reflection.Parse(list.Value as string);
            }
        }
        public const string ExplainKey = "UI.Explain";
        void taskEvent_OnEndProcess(TaskInstance task, UMC.WorkFlow.InstanceEventArgs eventArgs)
        {
            var taskMessages = new List<TaskMessage>();
            var items = eventArgs.Runtime.Items;//[ExplainKey];
            string Explain = String.Format("{0}", items[ExplainKey]);
            string Subject = String.Format("{0}", items["UI.Subject"]);
            var SessionId = (ulong)items[TaskRuntime.EVENT_SESSION_ID];

            var appleys = new List<TaskApproving>(DataFactory.Instance().TaskApproving(task.InstanceId));
            // var ApprovingEntity = TaskRuntime.Database.ObjectEntity<TaskApproving>();
            // ApprovingEntity.Where.And().Equal(new TaskApproving { InstanceId = task.InstanceId })
            // .Entities.Query(dr => appleys.Add(dr));

            if (task.Status == TaskStatus.Completed)
            {
                foreach (var a in appleys)
                {
                    DataFactory.Instance().Delete(a);
                }
                // ApprovingEntity.Where.Reset().And().Equal(new TaskApproving { InstanceId = task.InstanceId });
                // ApprovingEntity.Delete();
            }
            else if (task.Status == TaskStatus.Termination || task.Status == TaskStatus.Locked)
            {

                TaskApproving mes = new TaskApproving { Subject = Subject };
                if (task.Status == TaskStatus.Termination)
                {
                    mes.Status = task.Status == TaskStatus.Termination ? ShapeStatus.Terminated : ShapeStatus.Rejected;
                }
                else
                {
                    mes.Status = ShapeStatus.Locked;
                }
                mes.Sender = eventArgs.Identity.Username;
                mes.SenderAlias = eventArgs.Identity.Alias;

                DataFactory.Instance().Put(mes);
                // ApprovingEntity.Where.And().Equal(new TaskApproving { InstanceId = task.InstanceId });
                // ApprovingEntity.Update(mes);

            }
            else if (task.Status == TaskStatus.InReview)
            {
                List<TaskApproving> appls = new List<TaskApproving>();
                var exists = new List<String>();

                for (int i = 0; i < task.Shapes.Count; i++)
                {
                    Shape shape = task.Shapes[i];
                    if (shape.Status == ShapeStatus.Activation)
                    {
                        exists.Add(shape.Id);
                        if (appleys.Exists(c => c.ShapeId == shape.Id) == false)
                        {
                            if (shape.Identity.Username.StartsWith("~") == false)
                            {
                                appls.Add(new TaskApproving
                                {
                                    InstanceId = task.InstanceId,
                                    TaskId = task.TaskId,
                                    Subject = Subject,
                                    Username = shape.Identity.Username,
                                    Status = shape.Status,
                                    ShapeId = shape.Id,
                                    ActiveTime = DateTime.Now,
                                    Proposer = task.Identity.Username,
                                    Sender = eventArgs.Identity.Username,
                                    SenderAlias = eventArgs.Identity.Alias
                                });
                            }
                        }
                    }
                }

                foreach (var v in appleys)
                {
                    if (exists.Exists(c => c == v.ShapeId) == false)
                    {
                        DataFactory.Instance().Delete(v);
                    }
                }
                // ApprovingEntity.Where.Reset().And().Equal(new TaskApproving
                // {
                //     InstanceId = task.InstanceId
                // }).And().NotIn(new TaskApproving { ShapeId = exists[0] }, exists.ToArray()).Entities.Delete();



                if (appls.Count > 0)
                {
                    foreach (var v in appls)
                    {
                        DataFactory.Instance().Put(v);
                    }
                }
                foreach (var m in appls)
                {

                    taskMessages.Add(new TaskMessage()
                    {
                        Id = Utility.NewId(),
                        SessionId = SessionId,
                        Subject = Subject,
                        Type = 1,
                        CreationTime = DateTime.Now,
                        ShapeId = m.ShapeId,
                        Sender = eventArgs.Identity.Username,
                        SenderAlias = eventArgs.Identity.Alias,
                        Proposer = task.Identity.Username,
                        ProposerAlias = task.Identity.Alias,
                        Status = 0,
                        InstanceId = task.InstanceId,
                        TaskId = task.TaskId,
                        Username = m.Username,
                        Alias = m.Alias
                    });

                }



            }
            if (eventArgs.Identity.Username.StartsWith("~") == false)
            {
                TaskHistory record = new TaskHistory
                {
                    Subject = Subject,
                    Proposer = task.Identity.Username,
                    ProposerAlias = task.Identity.Alias,
                    InstanceId = task.InstanceId,
                    TaskId = task.TaskId,
                    CommandType = eventArgs.CommandType,
                    Status = task.Status,
                    Description = Explain,
                    IdentityName = eventArgs.Identity.Username,
                    RevertTime = DateTime.Now,
                    SrcIdentityName = eventArgs.Shape.Identity.Username
                };
                DataFactory.Instance().Put(record);

                Utility.Each(DataFactory.Instance().TaskHistory(task.InstanceId), e =>
                {
                    e.Status = task.Status;
                    DataFactory.Instance().Put(e);
                });


                // UMC.WorkFlow.TaskRuntime.Database.ObjectEntity<TaskHistory>()
                //     .Where.And().Equal(new TaskHistory
                //     {
                //         InstanceId = task.InstanceId,
                //         IdentityName = eventArgs.Identity.Username
                //     })
                // .Entities.IFF(e => e.Update(record) == 0, e => e.Insert(record))
                //     .Where.Reset().And().Equal(new TaskHistory { InstanceId = task.InstanceId })
                //     .Entities.Update(new TaskHistory
                //     {
                //         Status = task.Status
                //     });
            }
            TaskRequest reg = new TaskRequest
            {
                InstanceId = task.InstanceId,
                Subject = Subject,
                TaskId = task.TaskId, /*reg.TaskName = task.Name;*/
                Description = Explain,
                StartTime = task.StartTime,
                Username = task.Identity.Username,
                Alias = task.Identity.Alias,
                FinishTime = task.FinishTime,
                Activer = eventArgs.Identity.Username,
                ActiverAlias = eventArgs.Identity.Alias,
                ActiveTime = DateTime.Now,
                Status = task.Status
            };
            if (eventArgs.CommandType != CommandType.Submit)
            {
                taskMessages.Add(new TaskMessage()
                {
                    Id = Utility.NewId(),
                    Subject = Subject,
                    Type = 0,
                    CreationTime = DateTime.Now,
                    ShapeId = eventArgs.Shape.Id,
                    Sender = eventArgs.Identity.Username,
                    SenderAlias = eventArgs.Identity.Alias,
                    SessionId = SessionId,
                    Proposer = task.Identity.Username,
                    ProposerAlias = task.Identity.Alias,
                    Status = 0,
                    InstanceId = task.InstanceId,
                    TaskId = task.TaskId,
                    Username = reg.Username,
                    Alias = reg.Alias
                });
            }
            if (taskMessages.Count > 0)
            {

                DataFactory.Instance().Put(taskMessages);
                // UMC.WorkFlow.TaskRuntime.Database.ObjectEntity<TaskMessage>().Insert(taskMessages.ToArray());
            }
            if (task.Status == TaskStatus.Completed)
            {
                DataFactory.Instance().Delete(new TaskRequest { InstanceId = task.InstanceId });
            }
            else
            {
                DataFactory.Instance().Put(reg);
                //     UMC.WorkFlow.TaskRuntime.Database.ObjectEntity<TaskRequest>()
                //    .Where.And().Equal(new TaskRequest { InstanceId = task.InstanceId })
                //    .Entities.IFF(e => e.Update(reg) == 0, e => e.Insert(reg));
            }

            Subscribe(task, eventArgs, SessionId);
            Save(task, eventArgs, appleys.Find(g => g.ShapeId == eventArgs.Shape.Id), SessionId, Explain);
        }
        void Subscribe(TaskInstance task, InstanceEventArgs e, ulong SessionId)
        {
            var subs = new List<TaskSubscribe>();
            // UMC.WorkFlow.TaskRuntime.Database.ObjectEntity<TaskSubscribe>()
            //    .Where.And().Equal(new TaskSubscribe { TaskId = task.TaskId })
            Utility.Each(DataFactory.Instance().TaskSubscribe(task.TaskId), dr =>
            {
                if (String.IsNullOrEmpty(dr.ShapeId) == false && String.Equals(dr.ShapeId, "ALL", StringComparison.CurrentCultureIgnoreCase) == false)
                {
                    if (e.Shape.Id.StartsWith(dr.ShapeId) == false)
                    {
                        return;
                    }
                    if (task.Shapes.Exists(s => s.Id.StartsWith(dr.ShapeId) && s.Status == ShapeStatus.Activation))
                    {
                        return;
                    }
                }
                subs.Add(dr);
            });
            System.Collections.IDictionary dic = new System.Collections.Hashtable(e.Runtime.Items);
            var subject = Utility.Format("{UI.Subject}", dic);
            var taskMessages = new List<TaskMessage>();
            foreach (var sub in subs)
            {
                var es = Utility.Enum(sub.SubscribeEvent ?? CommandType.Undefine);
                foreach (var ct in es)
                {
                    if (ct == e.CommandType)
                    {
                        taskMessages.Add(new TaskMessage()
                        {
                            Id = Utility.NewId(),
                            Subject = subject,
                            Type = 4,
                            CreationTime = DateTime.Now,
                            ShapeId = e.Shape.Id,
                            Status = 0,
                            InstanceId = task.InstanceId,
                            Sender = e.Identity.Username,
                            SenderAlias = e.Identity.Alias,
                            Proposer = task.Identity.Username,
                            ProposerAlias = task.Identity.Alias,
                            TaskId = task.TaskId,
                            SessionId = SessionId,
                            Username = sub.Username,
                            Alias = sub.Alias
                        });

                    }
                }

            }
            if (taskMessages.Count > 0)
            {
                DataFactory.Instance().Put(taskMessages.ToArray());
            }
        }
        void Save(TaskInstance sender, InstanceEventArgs e, TaskApproving approving, ulong SessionId, string Explain)
        {
            // var entity = UMC.WorkFlow.TaskRuntime.Database.ObjectEntity<TaskLog>();


            var taskLog = new TaskLog
            {
                Id = SessionId,
                Content = JSON.Serialize(sender, true),
                InstanceId = sender.InstanceId,
                ActivationTime = approving != null ? approving.ActiveTime : DateTime.Now,
                CreateTime = DateTime.Now,
                TaskId = sender.TaskId,
                Username = e.Identity.Username,
                Alias = e.Identity.Alias,
                ShapeId = e.Shape.Id,
                CommandType = e.CommandType,
                Explain = Explain,
                ShapeUsername = sender.Identity.Username,
                ShapeAlias = sender.Identity.Alias,
                ShapeText = e.Shape.Text
            };
            DataFactory.Instance().Put(taskLog);

        }

    }
}
